package com.xszx.file.controller;

import com.xszx.server.dto.AjaxJson;
import com.xszx.server.entity.UploadFile;
import com.xszx.server.service.UploadFileService;
import com.xszx.server.util.Base64ToMultipartFile;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

@RestController
public class BigFileUpLoadController {
    @Value("${file.path}")
    private String FILE_PATH;//物理路径

    @Value("${file.domain}")
    private String DOMAIN_PATH;//访问路径

    @Resource
    private UploadFileService uploadFileService;
    //进行文件的上传
    @PostMapping("/uploadBigfile")
    public AjaxJson uploadBigfile(@RequestBody UploadFile uploadFile) throws Exception {
        //将分片的内容读取出来
        MultipartFile file = Base64ToMultipartFile.base64ToMultipart(uploadFile.getShard());
        //指定文件的传输路径
        uploadFile.setUse("section");//用途

        //设置path属性(文件的相对路径)
        uploadFile.setPath(uploadFile.getUse()+File.separator+uploadFile.getFileKey()+"."+uploadFile.getSuffix());//section/4syXW4DAk8oAMY4ksUke6.mp4
        //给当前的要上传的分片起名称
        File fullDir = new File(FILE_PATH +uploadFile.getUse()+File.separator+uploadFile.getFileKey()+"."+uploadFile.getSuffix()+"."+uploadFile.getShardIndex());

        if(!fullDir.getParentFile().exists()){ //判断文件父目录是否存在
            fullDir.getParentFile().mkdirs();
        }
        //进行文件的保存
        file.transferTo(fullDir);

        //将当前分片的内容存储在数据库中
        uploadFileService.saveOrUpdate(uploadFile);

        //修改当前文件的路劲
        uploadFile.setPath(DOMAIN_PATH+uploadFile.getPath());

        //合并所有分片
        if(uploadFile.getShardIndex() == uploadFile.getShardTotal()){
            merge(uploadFile);
        }

        return AjaxJson.success().put("uploadFile",uploadFile);
    }

    //查看数据表中是否有上传过的文件
    @GetMapping("/check/{fileKey}")
    public AjaxJson check(@PathVariable("fileKey") String fileKey){
        //从数据库中获取文件的上传信息
        UploadFile uploadFile = uploadFileService.getUploadFileByFileKey(fileKey);
        if(uploadFile != null){
            uploadFile.setPath(DOMAIN_PATH+uploadFile.getPath());
        }
        return AjaxJson.success().put("uploadFile",uploadFile);
    }

    //合并分片
    public void merge(UploadFile uploadFile) throws Exception {
        System.out.println("合并分片开始");
        String path = uploadFile.getPath(); //http://127.0.0.1:9003/file/section\6sfSqfOwzmik4A4icMYuUe.mp4
        path = path.replace(DOMAIN_PATH, ""); //course\6sfSqfOwzmik4A4icMYuUe.mp4
        Integer shardTotal = uploadFile.getShardTotal();
        File newFile = new File(FILE_PATH + path);
        FileOutputStream outputStream = new FileOutputStream(newFile, true);//文件追加写入
        FileInputStream fileInputStream = null;//分片文件
        byte[] byt = new byte[10 * 1024 * 1024];
        int len;

        try {
            for (int i = 0; i < shardTotal; i++) {
                // 读取第i个分片
                fileInputStream = new FileInputStream(new File(FILE_PATH + path + "." + (i + 1))); //  course\6sfSqfOwzmik4A4icMYuUe.mp4.1
                while ((len = fileInputStream.read(byt)) != -1) {
                    outputStream.write(byt, 0, len);
                }
            }
        } catch (IOException e) {
            System.out.println("分片合并异常");
        } finally {
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
                outputStream.close();
                System.out.println("IO流关闭");
            } catch (Exception e) {
               e.printStackTrace();
            }
        }
        System.out.println("合并分片结束");
        System.gc();
        Thread.sleep(100);

        // 删除分片
        System.out.println("删除分片开始");
        for (int i = 0; i < shardTotal; i++) {
            String filePath = FILE_PATH + path + "." + (i + 1);
            File file = new File(filePath);
            boolean result = file.delete();
        }
        System.out.println("删除分片结束");
    }

}
